<template>
    <Teleport to="body">
        <Transition name="modal-fade">
            <div v-if="modelValue" class="modal-overlay" @click="handleOverlayClick">
                <div class="modal-container" :style="modalStyle" @mousedown="startDrag" @mousemove="onDrag"
                    @mouseup="stopDrag" @mouseleave="stopDrag">
                    <!-- 标题栏 -->
                    <div class="modal-header">
                        <slot name="header">
                            <h3>{{ title }}</h3>
                        </slot>
                        <button class="modal-close" @click="close">×</button>
                    </div>

                    <!-- 内容区 -->
                    <div class="modal-body">
                        <slot>
                            {{ content }}
                        </slot>
                    </div>

                    <!-- 按钮区 -->
                    <div class="modal-footer">
                        <slot name="footer">
                            <button class="modal-btn cancel" v-if="showCancel" @click="cancel">取消</button>
                            <button class="modal-btn confirm" @click="confirm">确定</button>
                        </slot>
                    </div>
                </div>
            </div>
        </Transition>
    </Teleport>
</template>

<script lang="ts" setup>
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';

const props = defineProps({
    modelValue: Boolean, // v-model绑定值
    title: {
        type: String,
        default: '提示'
    },
    content: String,
    width: {
        type: [String, Number],
        default: '500px'
    },
    height: {
        type: [String, Number],
        default: 'auto'
    },
    showCancel: {
        type: Boolean,
        default: true
    },
    closeOnClickOverlay: {
        type: Boolean,
        default: true
    },
    draggable: {
        type: Boolean,
        default: true
    }
});

const emit = defineEmits(['update:modelValue', 'confirm', 'cancel']);

// 处理拖拽逻辑
const isDragging = ref(false);
const dragOffset = ref({ x: 0, y: 0 });
const position = ref({ x: 0, y: 0 });

const modalStyle = computed(() => {
    return {
        width: typeof props.width === 'number' ? `${props.width}px` : props.width,
        height: typeof props.height === 'number' ? `${props.height}px` : props.height,
        transform: `translate(${position.value.x}px, ${position.value.y}px)`
    };
});

function startDrag(event) {
    if (!props.draggable) return;

    // 只在点击标题栏时才能拖动
    if (event.target.closest('.modal-header')) {
        isDragging.value = true;
        dragOffset.value = {
            x: event.clientX - position.value.x,
            y: event.clientY - position.value.y
        };
    }
}

function onDrag(event) {
    if (isDragging.value) {
        position.value = {
            x: event.clientX - dragOffset.value.x,
            y: event.clientY - dragOffset.value.y
        };
    }
}

function stopDrag() {
    isDragging.value = false;
}

function close() {
    emit('update:modelValue', false);
}

function confirm() {
    emit('confirm');
    close();
}

function cancel() {
    emit('cancel');
    close();
}

function handleOverlayClick(event) {
    // 只有点击遮罩层而不是弹窗本身才关闭
    if (props.closeOnClickOverlay && event.target.classList.contains('modal-overlay')) {
        close();
    }
}

// 按ESC键关闭弹窗
function handleKeyDown(event) {
    if (event.key === 'Escape' && props.modelValue) {
        close();
    }
}

onMounted(() => {
    window.addEventListener('keydown', handleKeyDown);
});

onUnmounted(() => {
    window.removeEventListener('keydown', handleKeyDown);
});
</script>

<style scoped>
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}

.modal-container {
    background-color: #ffffff;
    border-radius: 4px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-width: 90%;
    max-height: 90%;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid #e8e8e8;
    cursor: move;
}

.modal-body {
    padding: 16px;
    overflow-y: auto;
    flex: 1;
}

.modal-footer {
    padding: 12px 16px;
    border-top: 1px solid #e8e8e8;
    text-align: right;
}

.modal-close {
    border: none;
    background: transparent;
    font-size: 20px;
    cursor: pointer;
    outline: none;
}

.modal-btn {
    padding: 8px 15px;
    margin-left: 10px;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    background: #fff;
    cursor: pointer;
}

.modal-btn.confirm {
    background-color: #409eff;
    color: #fff;
    border-color: #409eff;
}

/* 过渡动画 */
.modal-fade-enter-active,
.modal-fade-leave-active {
    transition: opacity 0.3s;
}

.modal-fade-enter-from,
.modal-fade-leave-to {
    opacity: 0;
}
</style>